<?php

require_once(getShopBasePath() . 'modules/klarna/api/kreditor.php');
/**
 * Extends core/oxpaymentgateway.
 *
 * Extended to take care of Klarna payments. If not a Klarna payment, the parent function will
 * be called.
 *
 * Inspired by: http://devzone.zend.com/article/4780 AND http://devzone.zend.com/article/7525
 *
 * @author Klarna
 */
class klarnaPaymentGateway extends klarnaPaymentGateway_parent {

	private $isInvoice = null;
	private $lang = null;
	private $kutil = null;
	private $kconf = null;
	private $country = null;
	private $user = null;
	private $dynv = null;
	private $p = null;

	/**
	 * Executes payment by connecting to Klarnas server and sending the needed information.
	 *
	 * @param double $dAmount Goods amount
	 * @param object &$oOrder User ordering object
	 *
	 * @Override
	 * @return bool returns true and invoice number on success, false and error on failure.
	 */
	public function executePayment($dAmount, &$oOrder) {
		if(!$this->kutil) {
			$this->kutil = oxNew('klarnautil');
		}

		$this->country = $this->kutil->getISOAlpha2($oOrder->getOrderUser());
		$this->lang = oxLang::getInstance();//->translateString( 'INC_HEADER_TITLEPAGE' )
		if(!$this->kutil->showPaymentFull($this->country, $oOrder->oxorder__oxcurrency->value)) {
			$this->_iLastErrorNo = $this->kutil->getPaymentErrorCode();
			$this->kutil->saveError($this->lang->translateString('KLARNA_CHANGED_CURRENCY'));
			return false;
		}

		if (@$this->_oPaymentInfo->oxuserpayments__oxpaymentsid->value != $this->kutil->getIName() &&
			@$this->_oPaymentInfo->oxuserpayments__oxpaymentsid->value != $this->kutil->getPPName() &&
			@$this->_oPaymentInfo->oxuserpayments__oxpaymentsid->value != $this->kutil->getSCName()) {
			return parent::executePayment($dAmount, &$oOrder);
		}

		//Inits all the private variables needed to execute the payment.
		$this->isInvoice = ($this->_oPaymentInfo->oxuserpayments__oxpaymentsid->value ==
							$this->kutil->getIName()) ? true : false;
		$this->kutil = $this->getKlarnaUtil();
		$this->kconf = $this->kutil->getKlarnaConfig();
		$this->user = $oOrder->getOrderUser();
		$this->dynv = $this->getDynValues($this->_oPaymentInfo->getDynValues());
		$this->p = $this->getPayment();

		$goods = array();

		foreach($oOrder->getOrderArticles() as $obj) {
			$goods[] = mk_goods_flags(	$obj->oxorderarticles__oxamount->value,
										$obj->oxorderarticles__oxartnum->value,
										$obj->oxorderarticles__oxtitle->value,
										$obj->oxorderarticles__oxbprice->value*100,
										$obj->oxorderarticles__oxvat->value,
										0, 32
									);
		}

		//Adds shipping cost to the goods list
		$goods[] = mk_goods_flags(	1, '', $oOrder->getDelSet()->oxdeliveryset__oxtitle->value,
									($oOrder->getOrderDeliveryPrice()->getBruttoPrice())*100,
									$this->kutil->getVat($oOrder->getOrderArticles()), 0, 40);

		//Adds invoice cost to the goods list
		if($this->isInvoice) {
			//$temp = 'klarnaconfig__invoicefee' . strtolower($this->country);
			$goods[] = mk_goods_flags(	1, '', $this->lang->translateString('KLARNA_INVOICE_FEE'),
										$oOrder->oxorder__oxpaycost->value*100,
										$this->kutil->getVat($oOrder->getOrderArticles()), 0, 32);
		}

		//Adds discount to the basket
		if($oOrder->oxorder__oxdiscount->value) {
			$goods[] = mk_goods_flags(	1, '', $this->lang->translateString('KLARNA_DISCOUNT'),
										$oOrder->oxorder__oxdiscount->value*100*-1,
										$this->kutil->getVat($oOrder->getOrderArticles()), 0, 32);
		}

		//Adds coupons to the goods list
		if($oOrder->oxorder__oxvoucherdiscount->value) {
			$goods[] = mk_goods_flags(	1, '', $this->lang->translateString('KLARNA_DISCOUNT'),
										$oOrder->oxorder__oxvoucherdiscount->value*100*-1,
										$this->kutil->getVat($oOrder->getOrderArticles()), 0, 32);
		}

		$eid = $this->kconf->klarnaconfig__eid->value;
		$secret = $this->kconf->klarnaconfig__secret->value;

		$clientIP = $_SERVER["REMOTE_ADDR"];
		$flags = $this->kconf->klarnaconfig__testmode->value == 0 ? 0 : $GLOBALS['KRED_TEST_MODE'];

		$goodsList = $goods;

		//Mostly deprecated non used variables.
		$estoreUser = "";
		$estoreOrderNo = "";
		$shipmentfee = 0;
		$shipmenttype = 1;
		$handlingfee = 0;
		$passwd = "";
		$newPasswd = "";
		$comment = "";
		$ready_date = "";
		$rand_string = "";
		$careof = "";

		$telno = $this->dynv[$this->p.'fon'] ? $this->dynv[$this->p.'fon'] : $this->user->oxuser__oxfon->value;
		$cellno = $this->dynv[$this->p.'mobfon'];
		$oOrder->oxorder__oxbillfon->rawValue = $telno ? $telno : $cellno;

		$email = $this->dynv[$this->p.'user'];
		$oOrder->oxorder__oxbillemail->rawValue = $email;

		$pno = $this->dynv[$this->p.'birth'];
		$fname = $this->user->oxuser__oxfname->value;
		$lname = $this->user->oxuser__oxlname->value;

		$city = $this->user->oxuser__oxcity->value;
		$postno = $this->user->oxuser__oxzip->value;

		if($this->country == 'DE') {
			$pno .= ($this->dynv[$this->p.'gender'] == 'M') ? 1 : 0;
			$street = $this->dynv[$this->p.'street'];
			$house_number = $this->dynv[$this->p.'streetnr'];

			$addr = mk_addr_de($careof, $street, $postno, $city, $telno, $cellno, $email, $house_number);

			$oOrder->oxorder__oxbillstreet->rawValue = $street;
			$oOrder->oxorder__oxbillstreetnr->rawValue = $house_number;

			$pno_encoding = $GLOBALS['PNO_DE'];
			$country = $GLOBALS['KRED_ISO3166_DE'];
			$language = $GLOBALS['KRED_ISO639_DE'];
			$currency = $GLOBALS['KRED_EUR'];
		} else if($this->country == 'SE') {
			$street = $this->user->oxuser__oxstreet->value . ' ' . $this->user->oxuser__oxstreetnr->value;

			$addr = mk_addr_se($careof, $street, $postno, $city, $telno, $cellno, $email);

			$pno_encoding = $GLOBALS['PNO_SE'];
			$country = $GLOBALS['KRED_ISO3166_SE'];
			$language = $GLOBALS['KRED_ISO639_SV'];
			$currency = $GLOBALS['KRED_SEK'];
		} else if($this->country == 'NO') {
			$street = $this->user->oxuser__oxstreet->value . ' ' . $this->user->oxuser__oxstreetnr->value;

			$addr = mk_addr_no($careof, $street, $postno, $city, $telno, $cellno, $email);

			$pno_encoding = $GLOBALS['PNO_NO'];
			$country = $GLOBALS['KRED_ISO3166_NO'];
			$language = $GLOBALS['KRED_ISO639_NB'];
			$currency = $GLOBALS['KRED_NOK'];
		} else if($this->country == 'FI') {
			$street = $this->user->oxuser__oxstreet->value . ' ' . $this->user->oxuser__oxstreetnr->value;

			$addr = mk_addr_fi($careof, $street, $postno, $city, $telno, $cellno, $email);

			$pno_encoding = $GLOBALS['PNO_FI'];
			$country = $GLOBALS['KRED_ISO3166_FI'];
			$language = $GLOBALS['KRED_ISO639_FI'];
			$currency = $GLOBALS['KRED_EUR'];
		} else if($this->country == 'DK') {
			$street = $this->user->oxuser__oxstreet->value . ' ' . $this->user->oxuser__oxstreetnr->value;

			$addr = mk_addr_dk($careof, $street, $postno, $city, $telno, $cellno, $email);

			$pno_encoding = $GLOBALS['PNO_DK'];
			$country = $GLOBALS['KRED_ISO3166_DK'];
			$language = $GLOBALS['KRED_ISO639_DA'];
			$currency = $GLOBALS['KRED_DKK'];
		} else if($this->country == 'NL') {
			$pno .= ($this->dynv[$this->p.'gender'] == 'M') ? 1 : 0;
			$street = $this->dynv[$this->p.'street'];
			$house_number = $this->dynv[$this->p.'streetnr'];
			$houseextension = $this->dynv[$this->p.'houseextension'];

			$addr = mk_addr_nl($careof, $street, $postno, $city, $telno, $cellno, $email, $house_number, $houseextension);

			$oOrder->oxorder__oxbillstreet->rawValue = $street;
			$oOrder->oxorder__oxbillstreetnr->rawValue = $house_number;

			$pno_encoding = $GLOBALS['PNO_NL'];
			$country = $GLOBALS['KRED_ISO3166_NL'];
			$language = $GLOBALS['KRED_ISO639_NL'];
			$currency = $GLOBALS['KRED_EUR'];
		}

		if($this->isInvoice) {
			$pclass = -1;
			$ysalary = 0;
		} else {
			if($this->_oPaymentInfo->oxuserpayments__oxpaymentsid->value == $this->kutil->getPPName()) {
				$pclass = $this->dynv['kpppclassid'];
				$ysalary = $this->dynv['kppysalary'];
			} else {
				$pclass = $this->dynv['kscpclassid'];
				$ysalary = $this->dynv['kscysalary'];
			}
		}


		$status = add_transaction(	$eid, $estoreUser, $secret, $estoreOrderNo, $goodsList,
									$shipmentfee, $shipmenttype, $handlingfee, $pno, $fname,
									$lname, $addr, $passwd, $clientIP, $newPasswd, $flags,
									$comment, $ready_date, $rand_string, $currency, $country,
									$language, $pno_encoding, $pclass, $ysalary, &$result);

		if($status == 0) {
			$oOrder->save();
			$this->kutil->saveSM($result);
			$this->kutil->saveEmailSM($result);
			return true;
		} else {
			$this->_iLastErrorNo = $this->kutil->getPaymentErrorCode();
			$this->kutil->saveError($result);
			return false;
		}
	}

	/**
	 * Used to return the klarnautil object. The idea is to make it easy to replace what is
	 * returned.
	 *
	 * @return klarnautil
	 */
	protected function getKlarnaUtil() {
		return oxNew('klarnautil');
	}

	/**
	 * Takes in a list and returns a array. For easier access to the data.
	 * Inspired by: http://devzone.zend.com/article/4780
	 *
	 * @param oxList $list
	 *
	 * @return array
	 */
	protected function getDynValues($list) {
		$dynVal = array();
		foreach ($list as $obj) {
			$key = $obj->name;
			$value = $obj->value;
			$dynVal[$key] = $value;
		}
		return $dynVal;
	}

	protected function getPayment() {
		if($this->_oPaymentInfo->oxuserpayments__oxpaymentsid->value == $this->kutil->getIName()) {
			return 'ki';
		} else if($this->_oPaymentInfo->oxuserpayments__oxpaymentsid->value == $this->kutil->getPPName()) {
			return 'kpp';
		} else if($this->_oPaymentInfo->oxuserpayments__oxpaymentsid->value == $this->kutil->getSCName()) {
			return 'ksc';
		}

		return null;
	}
}
?>